<template>
  <div style="width: 100%;height: 100%;display: flex">
    <div class="left_box">
      <div class="code_box">
        <ace-editor style="width: 100%;height: 100%" :html-text-value="htmlStr" :ts-text-value="tsStr"></ace-editor>
      </div>
    </div>
    <div id="load4490_box">
      <div class="popup_box">
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
import {initMap} from "@/widgets/modelExample_cesium/common/initMap";
import {nextTick, onMounted, ref} from "vue";
import {
  loadGltf,
  setEntityFloat,
  setEntityRotate,
  craeteDynamicCricleGraphics,
  loadModelLayer
} from "../../common/loadLayers";
import gisTools from "../../common/GisTools";
import AceEditor from "@/components/aceEditor.vue";

const htmlStr = ref(`
  <template>
  <div style="width: 100%;height: 100%;display: flex">
    <div id="load4490_box">
      <div class="popup_box">
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
import {initMap} from "@/widgets/modelExample_cesium/common/initMap";
import {nextTick, onMounted, ref} from "vue";
import {
  loadGltf,
  setEntityFloat,
  setEntityRotate,
  craeteDynamicCricleGraphics,
  loadModelLayer
} from "../../common/loadLayers";
import gisTools from "../../common/GisTools";


const renderStart = () => {
  loadModelLayer(
      cViewer.value,
      '/public/otherModal/cityHouse/tileset.json',
      "md2_tiles",
      {
        spaceError:1,
        bLocTo: false,
        height: 0,
        offset: {
          "tx": 113.58,
          "ty": 34.78,
          "tz": 0,
          "rx": 0,
          "ry": 0,
          "rz": 0
        }
      }
  );
  gisTools.cameraFlyToPoint(cViewer.value,[113.59, 34.74],3000)
 let entity= loadGltf(
      cViewer.value,
      '/public/otherModal/zhui.glb',
      [113.59, 34.74, 400],
      false
  )
  setEntityRotate(entity,{
    position:{"lon":113.59,"lat":34.74,height:50},
    rotateSacle:4,
  })
  setEntityFloat(entity,{
    position:{
      "lon":113.59,
      "lat": 34.74,
      "height":400
    } ,
    maxHeiht: 100,
    speed: 0.5,
  })
  craeteDynamicCricleGraphics(cViewer.value,{
    center: { lon: 113.59, lat: 34.74, height: 1 },
    radius: 800,
    scale1: 1500,
    rotateScale:0.01,
    image:"texturex/circle_bg.png"
  })
}
const cViewer = ref();
onMounted(() => {
  cViewer.value = initMap("load4490_box")
  nextTick(()=>{
    renderStart();
  })
})
<\/script>

<style lang="scss" scoped>
#load4490_box {
  width: 60%;
  height: 100%;
}

.popup_box {
  position: fixed;
  left: calc(40% + 40px);
  min-width: 100px;
  width: auto;
  top: 80px;
  height: 60px;
  z-index: 10;
}
</style>
`);

const tsStr = ref(`
import {
    ArcGisMapServerImageryProvider,
    WebMapTileServiceImageryProvider,
} from 'cesium'
import * as Cesium from "cesium";
import defaultImage from "@/assets/img/location.png";
import {getAssetsFile} from "@/utils/utils";

   /**
 * 设置实体Entity旋转
 * @param entity
 * @param  {object} options
 * @param {object} options.position - 原始位置  eg:{"lon":113.24,"lat":21.21,"height":1}
 * @param {number} options.rotateSacle - 旋转比例   default:4
 */
const setEntityRotate = (entity: any, options: any) => {
    let {position, rotateSacle} = options;
    if (position) {
        entity.position = new Cesium.CallbackProperty(function () {
            return Cesium.Cartesian3.fromDegrees(position['lon'], position['lat'], position['height']);
        }, false);
    }
    let rotateParams = {heading: 0, pitch: 0, roll: 0}
    Object.assign(rotateParams, {scale: rotateSacle})
    entity.orientation = new Cesium.CallbackProperty(function () {
        if (rotateSacle > 0) {
            rotateParams.heading += rotateSacle;
            if (rotateParams.heading === 360) {
                rotateParams.heading = 0;
            }
        }
        return Cesium.Transforms.headingPitchRollQuaternion(
            Cesium.Cartesian3.fromDegrees(position['lon'], position['lat'], position['height']),
            new Cesium.HeadingPitchRoll(
                Cesium.Math.toRadians(rotateParams.heading),
                Cesium.Math.toRadians(rotateParams.pitch),
                Cesium.Math.toRadians(rotateParams.roll)
            )
        );
    }, false);
}

/**
 * 实体上下浮动动画
 * @param entity
 * @param  {object} options
 * @param {object} options.position - 原始位置  eg:{"lon":113.24,"lat":21.21,"height":1}
 * @param {number} options.minHeiht - 最小高度   default:5
 * @param {number} options.maxHeiht - 最大高度  default:100
 * @param {number} options.speed - 高度  default:0.05
 */
const setEntityFloat = (entity: any, options: any) => {
    let {minHeiht, maxHeiht, speed, position} = options;
    if (!minHeiht) {
        minHeiht = 5
    }
    if (!maxHeiht) {
        maxHeiht = 100
    }
    if (!speed) {
        speed = 0.06
    }
    ;
    let flag = false;
    let bg_minHeiht = minHeiht;
    if (position) {
        entity.position = new Cesium.CallbackProperty(function () {
            if (minHeiht >= maxHeiht || minHeiht <= bg_minHeiht) {
                flag = !flag;
            }
            flag ? (minHeiht += speed) : (minHeiht -= speed);
            position.height = minHeiht;
            return Cesium.Cartesian3.fromDegrees(position['lon'], position['lat'], position['height']);
        }, false);
    }
}

/**
 * 创建动态旋转圆-使用图片做材质基底
 * @param viewer
 * @param  {object} options
 * @param {object} options.center - 中心坐标数组  eg:{"lon":113.24,"lat":21.21,"height":1}
 * @param {number} options.radius - 半径   default:800
 * @param {number} options.rotateScale - 旋转频率，越大越快  default:0.05
 * @param {number} options.height - 高度  default:1
 * @param {number} options.scale1 - 外圆缩放比例 default:1500
 * @param {number} options.scale2 - 内圆缩放比例  default:undefined
 * @param {string} options.image - 材质图片  eg:"static/data/images/Textures/circle_bg.png"
 * @desc 注：options.scale2=options.radius 旋转材质无缩放的动画
 */
const craeteDynamicCricleGraphics = (viewer: any, options: any) => {
    //默认初始化的参数
    let defaultOptions:any={
        radius:800,
        rotateScale:0.05,
        height:1,
        scale1:1500,
        image:"texturex/circle_bg.png"
    }
    Object.assign(defaultOptions,options)
    let {center, radius, rotateScale, height, scale1, scale2, image} = defaultOptions;
    if (!center) {
        return;
    }
    let startRotation = 0;
    //创建材质
    let material = new Cesium.ImageMaterialProperty({
        image:getAssetsFile(image),
        transparent: true,
    });
    let entity: any = new Cesium.Entity();
    entity.position = new Cesium.CallbackProperty(function () {
        return Cesium.Cartesian3.fromDegrees(center['lon'], center['lat'], center['height']);
    }, false);
    entity.orientation = new Cesium.CallbackProperty(function () {
        return Cesium.Transforms.headingPitchRollQuaternion(
            Cesium.Cartesian3.fromDegrees(center['lon'], center['lat'], center['height']),
            new Cesium.HeadingPitchRoll(
                Cesium.Math.toRadians(0),
                Cesium.Math.toRadians(0),
                Cesium.Math.toRadians(0)
            )
        );
    }, false);
    let bg_scale = radius;
    let flag = false;
    let updateScalerAxis = () => {     //外圈缩放
        if (radius >= scale1 || radius <= bg_scale) {
            flag = !flag;
        }
        flag ? (radius += 2) : (radius -= 2);
    };
    let updateScalerAxis2 = () => {
        scale2 >= radius ? (radius += 2) : (radius = bg_scale);
    };
    //实质就是纹理旋转控制
    entity.ellipse = {
        material: material,
        height: height,
        semiMajorAxis: new Cesium.CallbackProperty(function () {
            return radius;
        }, false),
        semiMinorAxis: new Cesium.CallbackProperty(function () {
            return radius;
        }, false),
        stRotation: new Cesium.CallbackProperty(function () {
            if (rotateScale > 0) {
                startRotation += rotateScale;
                if (startRotation >= 360) {
                    startRotation = 0;
                }
            }
            if (scale1) updateScalerAxis();
            if (scale2) updateScalerAxis2();
            return startRotation;
        }, false),
    };
    viewer.entities.add(entity);
    return entity;
}

/**
 * 加载gltf/glb模型数据
 * @param viewer
 * @param url
 * @param jwd
 */
const loadGltf = (viewer: any, url: string, jwd: [number, number, number], isTracked: boolean = true) => {
    let position = Cesium.Cartesian3.fromDegrees(jwd[0], jwd[1], jwd[2]);
    const heading = Cesium.Math.toRadians(135);
    const pitch = 0;
    const roll = 0;
    const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
    const orientation = Cesium.Transforms.headingPitchRollQuaternion(
        position,
        hpr
    );
    const entity = viewer.entities.add({
        position: position,
        orientation: orientation,
        model: {
            uri: url,
            minimumPixelSize: 128,
            maximumScale: 20000,
        },
    });
    if (isTracked) {
        viewer.trackedEntity = entity;
    }
    return entity;
}

export {
   loadGltf,
   setEntityRotate,
   setEntityFloat,
   craeteDynamicCricleGraphics
}

`);

const renderStart = () => {
  loadModelLayer(
      cViewer.value,
      '/public/otherModal/cityHouse/tileset.json',
      "md2_tiles",
      {
        spaceError:1,
        bLocTo: false,
        height: 0,
        offset: {
          "tx": 113.58,
          "ty": 34.78,
          "tz": 0,
          "rx": 0,
          "ry": 0,
          "rz": 0
        }
      }
  );
  gisTools.cameraFlyToPoint(cViewer.value,[113.59, 34.74],3000)
 let entity= loadGltf(
      cViewer.value,
      '/public/otherModal/zhui.glb',
      [113.59, 34.74, 400],
      false
  )
  setEntityRotate(entity,{
    position:{"lon":113.59,"lat":34.74,height:50},
    rotateSacle:4,
  })
  setEntityFloat(entity,{
    position:{
      "lon":113.59,
      "lat": 34.74,
      "height":400
    } ,
    maxHeiht: 100,
    speed: 0.5,
  })
  craeteDynamicCricleGraphics(cViewer.value,{
    center: { lon: 113.59, lat: 34.74, height: 1 },
    radius: 800,
    scale1: 1500,
    rotateScale:0.01,
    image:"texturex/circle_bg.png"
  })
}
const cViewer = ref();
onMounted(() => {
  cViewer.value = initMap("load4490_box")
  nextTick(()=>{
    renderStart();
  })
})
</script>

<style lang="scss" scoped>
.left_box {
  width: 40%;
  height: 100%;
  display: flex;
  flex-direction: row-reverse;

  .code_box {
    margin: 10px;
    width: calc(100% - 220px);
    height: calc(100% - 20px);
    background-color: #ffffff;
    color: #000;
    overflow-x: hidden;
    overflow-y: auto;
  }
}

#load4490_box {
  width: 60%;
  height: 100%;
}

.popup_box {
  position: fixed;
  left: calc(40% + 40px);
  min-width: 100px;
  width: auto;
  top: 80px;
  height: 60px;
  z-index: 10;
}
</style>
